﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using System.Net;
using System.Threading;
using System.IO;
using System.Diagnostics;
using AutoUpdater.UpdateSerivce;

namespace AutoUpdater {
    public partial class AutoUpdate : DevExpress.XtraEditors.XtraForm {
        //关闭进度条的委托
        public delegate void CloseProgressDelegate();
        //声明关闭进度条事件
        public event CloseProgressDelegate CloseProgress;
        //webservice服务
        UpdateSerivce.UpdateSerivceSoapClient service = null;
        WebClient wc = null;
        //获取下载地址
        string url;
        //获取升级压缩包
        string[] zips;
        //当前正在下载的zips下标
        int zipsIndex = 0;
        //上一次的下载流量
        long preBytes = 0;
        //当前下载流量
        long currBytes = 0;
        //获取服务器版本号
        string serviceVersion;

        public AutoUpdate() {
            InitializeComponent();
            service = new UpdateSerivce.UpdateSerivceSoapClient();
            url = service.GetURL(Guid.Empty);//获取下载地址
            serviceVersion = service.GetVersion(Guid.Empty);
            ArrayOfString str = service.GetZips(Guid.Empty);//获取升级压缩包
            zips = str.ToArray();
        }

        private void AutoUpdater_Load(object sender, EventArgs e) {
            try {
                this.lblMSG.Text = "正在检查更新...";
                IniClass ini = new IniClass(Application.StartupPath + @"\update.ini");
                //客户端版本
                string clientVersion = ini.IniReadValue("update", "version");
                if (clientVersion != serviceVersion) {
                    timer1.Start();
                    Thread downThread = new Thread(new ThreadStart(DownLoad));
                    downThread.IsBackground = true;
                    downThread.Start();
                } else {
                    //this.Visible = false;
                    this.lblMSG.Text = "已是最新版！";
                    XtraMessageBox.Show("已是最新版！");
                    this.Close();
                }
            } catch (Exception ex) {
                XtraMessageBox.Show("更新出错，请重试！");
                this.Close();
            }
        }

        /// <summary>
        /// 下载更新
        /// </summary>
        private void DownLoad() {
            try {
                CloseProgress += new CloseProgressDelegate(frmUpdate_CloseProgress);
                if (zips.Length > 0) {
                    wc = new WebClient();
                    wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
                    wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
                    wc.DownloadFileAsync(new Uri(url + zips[zipsIndex]), zips[zipsIndex]);
                } else {
                    frmUpdate_CloseProgress();//调用关闭进度条事件
                }
            } catch (Exception ex) {
                XtraMessageBox.Show("更新出错，请重试！");
                this.Close();
            }
        }

        /// <summary>
        /// 下载完成后触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) {
            try {
                zipsIndex++;
                if (zipsIndex < zips.Length) {
                    wc = new WebClient();
                    wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
                    wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
                    wc.DownloadFileAsync(new Uri(url + zips[zipsIndex]), zips[zipsIndex]);
                } else {
                    int maximum = ZipClass.GetMaximum(zips, Application.StartupPath);
                    foreach (string zip in zips) {
                        ZipClass.UnZip(Application.StartupPath + @"\" + zip, "", maximum, frmUpdate_SetProgress);
                        File.Delete(Application.StartupPath + @"\" + zip);
                    }
                    frmUpdate_CloseProgress();//调用关闭进度条事件
                }
            } catch (Exception ex) {
                XtraMessageBox.Show("更新出错，请重试！");
                this.Close();
            }
        }

        /// <summary>
        /// 下载时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) {
            try {
                if (this.InvokeRequired) {
                    this.Invoke(new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged), new object[] { sender, e });
                } else {
                    lblMSG.Text = "正在下载自解压包" + zips[zipsIndex] + "(" + (zipsIndex + 1).ToString() + "/" + zips.Length + ")";
                    progressBarX1.Maximum = 100;
                    progressBarX1.Value = e.ProgressPercentage;

                    currBytes = e.BytesReceived; //当前下载流量
                }
            } catch (Exception ex) {
                XtraMessageBox.Show("更新出错，请重试！");
                this.Close();
            }
        }

        /// <summary>
        /// 解压时进度条事件
        /// </summary>
        private void frmUpdate_SetProgress(int maximum, string msg) {
            try {
                if (this.InvokeRequired) {
                    this.Invoke(new ZipClass.SetProgressDelegate(frmUpdate_SetProgress), new object[] { maximum, msg });
                } else {
                    if (zipsIndex == zips.Length) {
                        //刚压缩完
                        progressBarX1.Value = 0;
                        zipsIndex++;
                    }
                    lblMSG.Text = "正在解压" + msg + "(" + (progressBarX1.Value + 1).ToString() + "/" + maximum + ")";
                    progressBarX1.Maximum = maximum;
                    progressBarX1.Value++;
                }
            } catch (Exception ex) {
                XtraMessageBox.Show("更新出错，请重试！");
                this.Close();
            }
        }

        /// <summary>
        /// 实现关闭进度条事件
        /// </summary>
        private void frmUpdate_CloseProgress() {
            try {
                if (this.InvokeRequired) {
                    this.Invoke(new CloseProgressDelegate(frmUpdate_CloseProgress), null);
                } else {
                    if (wc != null) {
                        wc.Dispose();
                    }
                    if (zips.Length > 0) {
                        XtraMessageBox.Show("升级成功！");
                    } else {
                        XtraMessageBox.Show("未找到升级包！");
                    }
                    IniClass ini = new IniClass(Application.StartupPath + @"\update.ini");
                    //更新成功后将版本写入
                    ini.IniWriteValue("update", "version", serviceVersion);
                    //退出升级程序
                    Application.Exit();
                    //打开主程序
                    Process.Start("work_log.exe");
                }
            } catch (Exception ex) {
                XtraMessageBox.Show("更新出错，请重试！");
                this.Close();
            }
        }

        private void timer1_Tick(object sender, EventArgs e) {
            //速度
            this.Text = ((currBytes - preBytes) / 1024).ToString() + "kb/s";
            //上一次下载流量
            preBytes = currBytes;
        }
    }
}